package com.producer.config;

import com.rabbitmq.client.AMQP;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component()
@PropertySource("classpath:rabbitmq.properties")
public class ConnectionFactoryConfig {
    @Value("${spring.rabbitmq.address}")
    private String address;
    @Value("${spring.rabbitmq.username}")
    private String userName;
    @Value("${spring.rabbitmq.password}")
    private String password;
    @Value("${spring.rabbitmq.virtualHost}")
    private String virtualHost;

    /**
     * cacheMode:
     * 1.当缓存模式设置成Connection时，连接会被缓存，createConnection()可能会创建新连接也可能从缓存中取；
     * 关闭连接时，如果缓存的连接数没有达到cacheSize则会被缓存起来，在这个模式下，由连接创建的channel也会被缓存
     * 2.当缓存模式设置成Connection时，connectionLimit会限制允许的连接总数，并且在获取新的连接时，如果连接数量已经达到connectionLimit，并且等待时间超过channelCheckoutTimeLimit，则会抛出异常。
     *
     * cache size:指可以缓存的Connection或者Channel数量，这个属性不限制连接的使用量，只决定连接关闭时是否缓存。
     *           当缓存模式为CacheMode.CHANNEL时，只会建立一个Connection,可以设置ChannelCacheSize，
     *           注意该数值不影响创建多少个channel，只是决定channel
     *           关闭时，是否缓存，当channel关闭时，如果存在的channel大于ChannelCacheSize，则销毁不会缓存
     *
     *
     *           当缓存模式为CacheMode.CONNECTION时，当连接关闭时，如果缓存的CONNECTION的数量还没有达到根据配置的cacheSize时，
     *           则连接会被缓存，该连接创建的Channel也会被缓存
     *           CacheMode.CONNECTION下不支持自动声明队列、exchange、binding
     *
     *           消费者一般为长链接，适用于CacheMode.CHANNEL
     *           生产者一般为短连接，适用于CacheMode.CONNECTION
     *
     * @return
     */
    @Bean("connectionFactory")
    @Primary
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setAddresses(address);
        cachingConnectionFactory.setUsername(userName);
        cachingConnectionFactory.setPassword(password);
        cachingConnectionFactory.setVirtualHost(virtualHost);
        //判断消息是否能够到达exchange
        cachingConnectionFactory.setPublisherConfirms(true);
        //判断消息是否能到达Queue
        cachingConnectionFactory.setPublisherReturns(true);
        //设置心跳 单位秒
        cachingConnectionFactory.setRequestedHeartBeat(10);
        cachingConnectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CONNECTION);
        cachingConnectionFactory.setConnectionLimit(1);
        cachingConnectionFactory.setConnectionCacheSize(2);
        cachingConnectionFactory.setConnectionTimeout(1000);
        //cachingConnectionFactory.setChannelCheckoutTimeout(1000);
        //cachingConnectionFactory.createConnection().createChannel().exchangeDeclare()
        return cachingConnectionFactory;
    }
}
